import Vue from 'vue'
import axios from 'axios'
import store from '@/store'
import qs from 'qs'
import $config from '@/config/defaultSettings'
import { sign } from '@/utils/sign'
import api from '@/api/index'
import notification from 'ant-design-vue/es/notification'
import { VueAxios } from './axios'
import { ACCESS_TOKEN } from '@/store/mutation-types'
// 创建 axios 实例
const service = axios.create({
  baseURL: process.env.VUE_APP_API_BASE_URL, // api base_url
  timeout: 6000 // 请求超时时间,
})

const err = (error) => {
  if (error.response) {
    const data = error.response.data
    const token = Vue.ls.get(ACCESS_TOKEN)
    notification.destroy()
    if (error.response.status === 401) {
      // notification.error({
      //   message: '401',
      //   description: data.message
      // })
      // if (token) {
      //   store.dispatch('Logout').then(() => {
      //     setTimeout(() => {
      //       window.location.reload()
      //     }, 1500)
      //   })
      // }
    } else if (error.response.status === 403) {
      notification.error({
        message: '403',
        description: data.path + ',' + data.message
      })
    } else if (error.response.status === 502) {
      notification.error({
        message: '服务器异常',
        description: '连接服务器失败'
      })
    } else if (error.response.status === 429) {
      notification.error({
        message: '服务器异常',
        description: '访问太过频繁，请稍后再试!'
      })
    } else {
      notification.error({
        message: '服务器异常',
        description: error.response.data.message
      })
    }
  }
  return Promise.reject(error)
}

// request interceptor
service.interceptors.request.use(config => {
  // 参数签名处理
  config = sign(config, $config.appId, $config.appSecretKey, 'SHA256')
  let method = config.method
  if (method === 'post') {
    if (config.data.params) {
      config.data.params = JSON.stringify(config.data.params)
    }
  }
  if (method === 'get') {
    config.params = { ...config.params }
  }
  const token = Vue.ls.get(ACCESS_TOKEN)
  if (token) {
    // 让每个请求携带自定义 token 请根据实际情况自行修改
    config.headers['Authorization'] = token
  }
  config.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
  return config
}, err)

// response interceptor
service.interceptors.response.use((response) => {
  if (response.data.code === httpClient.HTTP_OK_STATUS) {
    // 服务端定义的响应code码为0时请求成功
    // 使用Promise.resolve 正常响应
    return Promise.resolve(response.data)
  } else {
    // 使用Promise.reject 响应
    notification.error({
      message: response.data.message
    })
    return Promise.reject(response.data)
  }
}, err)

const installer = {
  vm: {},
  install(Vue) {
    Vue.use(VueAxios, service, api)
  }
}
const httpClient = {
  //网络请求成功状态值
  HTTP_OK_STATUS: 100,
  /**
   * get请求
   */
  get(me, option) {
    
    let params = option.data ? option.data : {}
    let config = { params, ...option }
    return service.get(option.url, config).then(res => {
      
      if (res.code === this.HTTP_OK_STATUS) {
        option.success && option.success(me, res.data, res.extra)
      } else {
        option.fail && option.fail(me, res.data)
      }
    }).catch(function(err) {
      option.error && option.error(me, err)
    })
  },

  /**
   * 分页请求
   */
  page(me, option) {
    let params = option.data ? option.data : {}
    let config = { params, ...option }
    return service.get(option.url, config).then(res => {
      if (res.code === this.HTTP_OK_STATUS) {
        option.success && option.success(me, res.data, res.extra)
      } else {
        option.fail && option.fail(me, res.data)
      }
    }).catch(function(err) {
      option.error && option.error(me, err)
    })
  },

  /**
   * post请求
   */
  post(me, option) {
    let params = option.data ? option.data : {}
    let config = {
      transformRequest: [function(data, headers) {
        return qs.stringify({ ...data })
      }]
    }
    return service.post(option.url, params, config).then(res => {
      if (res.code === this.HTTP_OK_STATUS) {
        option.success && option.success(me, res.data, res.extra)
        if (res.message) {
          me.$message.destroy()
          me.$message.success(res.message)
        }
        // me.$forceUpdate();
      } else {
        option.fail && option.fail(me, res.data)
      }
    }).catch(function(err) {
      if (err) {

      }
      option.error && option.error(me, err.response)
    })
  },
  /**
   * 添加或者更新
   */
  saveOrUpdate(me, option) {
    let api = option.api
    let url = api
    if (typeof api == 'object') {
      url = option.data.id ? api['update'] : api['add']
    } else {
      url = api
    }
    let data = option.data ? option.data : {}
    let requestBody = option.requestBody ? true : false
    let config = {}
    if (!requestBody) {
      config.transformRequest = [function(data, headers) {
        return qs.stringify({ ...data })
      }]
    }
    return service.post(url, data, config).then(res => {
      if (res.code === this.HTTP_OK_STATUS) {
        me.$bus.emit('reloadTable')
        me.$bus.emit('closeModal')
        option.success && option.success(me, res.data, res.extra)
        if (res.message != '') {
          me.$message.destroy()
          me.$message.success(res.message)
        }
        // me.$forceUpdate();
      } else {
        option.fail && option.fail(me, res.data)
      }
    }).catch(function(err) {
      if (err) {

      }
      option.error && option.error(me, err.response)
    })
  },
  /**
   * 带询问删除
   */
  del(me, option) {
    me.$confirm({
      title: '确认删除',
      content: '您确认要删除所选数据吗?',
      onOk: () => {
        let params = option.data ? option.data : {}
        let config = {
          transformRequest: [function(data, headers) {
            return qs.stringify({ ...data })
          }]
        }
        return service.post(option.url, params, config).then(res => {
          if (res.code === this.HTTP_OK_STATUS) {
            me.$bus.emit('reloadTable', name)
            option.success && option.success(me, res.data, res.extra)
            if (res.message) {
              me.$message.destroy()
              me.$message.success(res.message)
            }
          } else {
            option.fail && option.fail(me, res.data)
          }
        }).catch(function(err) {
          if (err) {
            if (err.response.status == 401) {
              //通知登录框弹出
              me.$store.commit('openLoginModel', true)
            }
          }
          option.error && option.error(me, err.response)
        })
      }
    })
  },
  put(me, option) {
    let params = option.data ? option.data : {}
    return service.put(option.url, params).then(res => {
      if (res.code === this.HTTP_OK_STATUS) {
        option.success && option.success(me, res.data, res.extra)
        if (res.message) {
          me.$message.destroy()
          me.$message.success(res.message)
        }
      } else {
        option.fail && option.fail(me, res.data)
      }
    }).catch(function(err) {
      if (err) {

      }
      option.error && option.error(me, err.response)
    })
  },
  /**
   * 导出文件
   */
  exportExcel(me, option) {
    let params = option.data ? option.data : {}
    const token =  Vue.ls.get('Access-Token')
    axios.post(process.env.VUE_APP_API_BASE_URL + '/' + option.url, qs.stringify(params), { responseType: 'blob', headers: { 'Authorization': token } }).then(res => {
      let fileName = decodeURI(res.headers['content-disposition'].split(';')[1].split('=')[1].replace(/"/g, ''))
      // 将`blob`对象转化成一个可访问的`url`
      let url = URL.createObjectURL(new Blob([res.data]))
      let link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.download = fileName
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      me.$message.destroy()
    }).catch(function(err) {
      if (err) {
      }
      option.error && option.error(me, err.response)
    })
  },
  /**
   * 带询问操作
   */
  confirm(me, option) {
    let content = option.content ? option.content : '确定执行该操作吗?'
    me.$confirm({
      title: '确认操作',
      content: content,
      onOk: () => {
        let params = option.data ? option.data : {}
        let config = {
          transformRequest: [function(data, headers) {
            return qs.stringify({ ...data })
          }]
        }
        return service.post(option.url, params, config).then(res => {
          if (res.code === this.HTTP_OK_STATUS) {
            option.success && option.success(me, res.data, res.extra)
            if (res.message) {
              me.$message.destroy()
              me.$message.success(res.message)
            }
          } else {
            option.fail && option.fail(me, res.data)
          }
        }).catch(function(err) {
          if (err) {
            if (err.response.status == 401) {
              //通知登录框弹出
              me.$store.commit('openLoginModel', true)
            }
          }
          option.error && option.error(me, err.response)
        })
      }
    })
  }
}
export {
  installer as VueAxios,
  service as axios,
  api,
  httpClient
}
